#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtConcurrent>
#include <QThread>
#include <memory>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


class TestThread : public QThread
{
    Q_OBJECT
public:
    explicit TestThread (QObject *parent = nullptr) :QThread(parent) { \
    }

    ~TestThread() {
        quitThread();
    }

    void setVar(const int& v) {
        m_var = v;
    }

    void quitThread() {
        if(isRunning()){
            condition.wakeOne();
            requestInterruption();
            wait();
        }
    }

    void startThread()
    {
        if(!isRunning())
            start();
        else
            condition.wakeOne();
    }

    void run() override
    {
        while(!isInterruptionRequested()) {
            m_lock.lock();
            /// do something
            qDebug() << "work thread id: " << QThread::currentThreadId();
            while(m_var < 100) {
                 emit signalVar(m_var);
                QThread::sleep(1);
                m_var ++;
            }

            /// do end
            condition.wait(&m_lock);
            m_lock.unlock();
        }
    }

signals:
    void signalVar(int);

private:
    QMutex m_lock;
    QWaitCondition condition;
    int m_var;
};

class Worker : public QObject
{
    Q_OBJECT

public:
    Worker(QObject *parent = nullptr) {}
    ~Worker(){}

    void setVar(const int& v) {
        m_var = v;
    }

signals:
    void signalVar(int);

public slots:
    void onPrintVar() {
        qDebug() << "work thread id: " << QThread::currentThreadId();
        while(m_var < 100) {
            emit signalVar(m_var);
            QThread::sleep(10);
            m_var ++;
        }
    }

private:
    int m_var;
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    void testThreadPool();
    void testConCurrent();
    void testMoveToThread();
    void testRun();
    void testMesQueue();



    Ui::MainWindow *ui;
    std::unique_ptr<TestThread> m_testThread = nullptr;
    QThread *m_workerThread = nullptr;
    std::unique_ptr<Worker>m_worker = nullptr;
};
#endif // MAINWINDOW_H
